home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
476-500
/
disk_497
/
windowshuffle
/
windowshuffle.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
21KB
|
684 lines
/*
* WindowShuffle.c
*
* Commodity
*
* Author: Stefan Sticht
*
* Copyright: source is public domain, no copyright
*
* Version history:
*
* V1.00 initial release
* V1.02 recompiled with main.c V1.02
* V1.03 completly rewritten; shared commodity code thrown away; smaller, uses less CPU time
* V1.04 now refuses to activate windows specified with REFUSE
* second pair of hotkeys for only Activate without WindowToFront()
* changed Priority to 21 to block out intuition for safety reasons
* V1.05 some really minor changes
*/
#define VERSION "V1.05"
/********************************************************************
* interfacing *
********************************************************************/
/*
* include files
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <intuition/intuitionbase.h>
#include <libraries/commodities.h>
#include <clib/alib_protos.h>
#include <clib/commodities_protos.h>
#include <pragmas/commodities_pragmas.h>
#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#include <clib/exec_protos.h>
#include <pragmas/exec_pragmas.h>
#include <clib/intuition_protos.h>
#include <pragmas/intuition_pragmas.h>
#ifdef DEBUG
#define printf KPrintF
#include <clib/dlib_protos.h>
#endif
/*
* prototypes
*/
long request(char *title, char *gadgets, char *text, ...);
struct Library *myopenlibrary(char *name, unsigned long version);
struct Window *lastwindow(struct Window *win);
struct Window *nextwindow(struct Window *win);
struct Window *prevwindow(struct Window *win);
void *retryallocmem(unsigned long size, long mode);
void processmessages(void);
/*
* global data defined in other moduls
*
* libraries opened by startup code; basepointers needed by function pragmas
*/
extern struct Library *DOSBase;
extern struct Library *SysBase;
/*
* Disable SAS/C CTRL/C handling
*/
void chkabort(void) {}
/********************************************************************
* global data *
********************************************************************/
#define TT_PREVAC "PREV_ACTIVE"
#define TT_NEXTAC "NEXT_ACTIVE"
#define TT_PREVBO "PREV_BOTH"
#define TT_NEXTBO "NEXT_BOTH"
/*
* definition of all messages (multi language support not completed yet)
*/
#ifdef GERMAN
#define RETRY_GADGETS "Wiederholen|Abbrechen"
#define RESUME_GADGETS "Weiter"
#define MSG_OUTOFMEM "Leider ein Speicherblock von %ld bytes\nnicht alloziert werden!"
#define MSG_LIBRARY_OPENERR "Die %s (V%ld+) kann nicht geöffnet werden!"
#define COM_NAME "Fensterln"
#define COM_DESCR "Nächstes/letztes Fenster aktivieren"
#define TT_BACKDROP "BACKDROP"
#define TT_NOWINTITLE "OHNETITEL"
#define TT_REFUSE "DIESENICHT"
#define MSG_REFUSE_TOO_COMPLEX "Leider muß " TT_REFUSE " ignoriert werden,\nda der Ausdruck zu komplex ist."
#define NO "NEIN"
#define YES "JA"
#else
#define RETRY_GADGETS "Retry|Cancel"
#define RESUME_GADGETS "Resume"
#define MSG_OUTOFMEM "Failure allocting %ld bytes of memory!"
#define MSG_LIBRARY_OPENERR "%s (V%ld+) can't be opened!"
#define COM_NAME "WindowShuffle"
#define COM_DESCR "Activate next/previous window"
#define TT_BACKDROP "BACKDROP"
#define TT_NOWINTITLE "WITHOUTTITLE"
#define TT_REFUSE "REFUSE"
#define MSG_REFUSE_TOO_COMPLEX TT_REFUSE " will be ignored\nas the pattern is too complex!"
#define YES "YES"
#define NO "NO"
#endif
#define COM_TITLE COM_NAME " " VERSION
#define CX_PRIORITY "CX_PRIORITY"
#define DEF_CX_PRIORITY 0
#define DEF_TT_PREVAC "lcommand lshift j"
#define DEF_TT_NEXTAC "lcommand lshift k"
#define DEF_TT_PREVBO "lcommand j"
#define DEF_TT_NEXTBO "lcommand k"
#define DEF_TT_BACKDROP NO
#define DEF_TT_NOWINTITLE NO
#define DEF_TT_REFUSE ""
/*
* data for cback.o
*/
long _stack = 4096l;
char *_procname = COM_NAME;
long _priority = 21l;
long _BackGroundIO = 1;
extern BPTR _Backstdout;
/*
* library base pointers
*/
struct IntuitionBase *IntuitionBase;
struct Library *CxBase;
struct Library *IconBase;
/*
* message port
*/
struct MsgPort *cxport = NULL;
/*
* signal flag
*/
unsigned long cxsigflag = 0l;
/*
* programtitle and version for Version command
*/
char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
/*
* helpstring
*/
#ifdef GERMAN
char helpstring[] =
"\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
"Aufruf: " COM_NAME " ["\
CX_PRIORITY "=<n>] [" TT_NEXTAC "=<Aktion>] [" TT_PREVAC "=<Aktion>] ["\
TT_NEXTBO "=<Aktion>] [" TT_PREVBO "=<Aktion>] [" TT_BACKDROP "=" YES "|" NO "] ["\
TT_NOWINTITLE "=" YES "|" NO "] [" TT_REFUSE "=<Jokerausdruck>]\n";
#else
char helpstring[] =
"\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
"Usage: " COM_NAME " ["\
CX_PRIORITY "=<n>] [" TT_NEXTAC "=<action>] [" TT_PREVAC "=<action>] ["\
TT_NEXTBO "=<action>] [" TT_PREVBO "=<action>] [" TT_BACKDROP "=" YES "|" NO "] ["\
TT_NOWINTITLE "=" YES "|" NO "] [" TT_REFUSE "=<wildcards>]\n";
#endif
/*
* the tooltypearray
*/
char **tooltypes;
/*
* our broker
*/
CxObj *broker = NULL;
struct NewBroker newbroker = {
NB_VERSION, /* BYTE nb_Version */
COM_NAME, /* BYTE *nb_Name */
COM_TITLE, /* BYTE *nb_Title */
COM_DESCR, /* BYTE *nb_Descr */
NBU_NOTIFY | NBU_UNIQUE, /* SHORT nb_Unique */
0, /* SHORT nb_Flags */
0, /* BYTE nb_Pri */
NULL, /* struct MsgPort nb_Port */
0 /* WORD nb_ReservedChannel */
};
#define NEXTAC 1
#define PREVAC 2
#define NEXTBO 3
#define PREVBO 4
/*
* pointer to refuse tokens
*/
char *refusetokens = NULL;
/*
* booleans for activation of backdrop windows and windows w/o title
*/
unsigned short backdrop;
unsigned short nowintitle;
/********************************************************************
* functions *
********************************************************************/
/*
* request(): a glue routine to EasyRequest as simple as printf plus
* titlestring, gadgettexts
*
* Input: char *title: pointer to the title of the requester
* char *gadgets: pointer to gadgettext
* char *text: text displayed in requester
*
* Result: same as EasyrequestArgs()
*
* !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
*/
long request(char *title, char *gadgets, char *text, ...)
{
/*
* structure textreq only needed in this function, so hide it here
* must be static, in order to be initialized only once
*/
static struct EasyStruct textreq = {
sizeof (struct EasyStruct), /* ULONG es_StructSize */
0l, /* ULONG es_Flags */
NULL, /* UBYTE *es_Title */
NULL, /* UBYTE *es_TextFormat */
NULL, /* UBYTE *es_GadgetFormat */
};
va_list ap;
long rc;
/*
* get start of variable arguments
*/
va_start(ap, text);
/*
* update textreq
*/
textreq.es_Title = (UBYTE *)title;
textreq.es_TextFormat = (UBYTE *)text;
textreq.es_GadgetFormat = (UBYTE *)gadgets;
/*
* win may be NULL
*/
rc = EasyRequestArgs(NULL, &textreq, NULL, ap);
va_end(ap);
return(rc);
}
/*
* myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
* if OpenLibrary() fails, to give the user a chance to
* copy the library to libs: and retry
* requires request(), see above
*/
struct Library *myopenlibrary(char *name, unsigned long version)
{
static char errortext[] = MSG_LIBRARY_OPENERR;
struct Library *libptr;
long ok = TRUE;
do {
if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
if (IntuitionBase) {
ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version);
}
else ok = FALSE;
}
} while (!libptr && ok);
#ifdef DEBUG
printf("myopenlibrary(%s, %ld) = 0x%lx\n", name, version, libptr);
#endif
return(libptr);
}
void *retryallocmem(unsigned long size, long mode)
{
void *addr;
do {
if (!(addr = AllocMem(size, mode))) {
if (!(request(COM_NAME ":", RETRY_GADGETS, MSG_OUTOFMEM, size)))
return(NULL);
}
} while (!addr);
return(addr);
}
void main(int argc, char *argv[])
{
CxObj *nextacfilter = NULL;
CxObj *prevacfilter = NULL;
CxObj *nextbofilter = NULL;
CxObj *prevbofilter = NULL;
struct Message *msg;
char *refuse;
char *nextackey;
char *prevackey;
char *nextbokey;
char *prevbokey;
unsigned long size = 0l;
if ((argc > 1) && (*argv[1] == '?')) {
/*
* display help string
*/
if (_Backstdout) {
Write(_Backstdout, helpstring, sizeof(helpstring) - 1l);
Close(_Backstdout);
}
return;
}
else if (argc && _Backstdout) Close(_Backstdout);
/*
* open required libraries first
*/
if (IntuitionBase = (struct IntuitionBase *)myopenlibrary("intuition.library", 37l)) {
if (CxBase = myopenlibrary("commodities.library", 37l)) {
if (IconBase = myopenlibrary("icon.library", 37l)) {
/*
* create tooltypes array (requires icon.library open!!!)
*/
tooltypes = (char **)ArgArrayInit(argc, argv);
/*
* create our message port
*/
if (cxport = CreateMsgPort()) {
cxsigflag = 1l << cxport->mp_SigBit;
/*
* set up some broker data
*/
newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY);
newbroker.nb_Port = cxport;
if (broker = CxBroker(&newbroker, NULL)) {
if ((nextackey = ArgString(tooltypes, TT_NEXTAC, DEF_TT_NEXTAC)) &&
*nextackey) {
if (nextacfilter = HotKey(nextackey, cxport, NEXTAC))
AttachCxObj(broker, nextacfilter);
} /* if nextackey */
if ((prevackey = ArgString(tooltypes, TT_PREVAC, DEF_TT_PREVAC)) &&
*prevackey) {
if (prevacfilter = HotKey(prevackey, cxport, PREVAC))
AttachCxObj(broker, prevacfilter);
} /* if prevackey */
if ((nextbokey = ArgString(tooltypes, TT_NEXTBO, DEF_TT_NEXTBO)) &&
*nextbokey) {
if (nextbofilter = HotKey(nextbokey, cxport, NEXTBO))
AttachCxObj(broker, nextbofilter);
} /* if nextbokey */
if ((prevbokey = ArgString(tooltypes, TT_PREVBO, DEF_TT_PREVBO)) &&
*prevbokey) {
if (prevbofilter = HotKey(prevbokey, cxport, PREVBO))
AttachCxObj(broker, prevbofilter);
} /* if prevbokey */
backdrop = (strcmpi((char *)ArgString(tooltypes, TT_BACKDROP, DEF_TT_BACKDROP),
YES)) ? FALSE : TRUE;
nowintitle = (strcmpi((char *)ArgString(tooltypes, TT_NOWINTITLE, DEF_TT_NOWINTITLE),
YES)) ? FALSE : TRUE;
refuse = (char *)ArgString(tooltypes, TT_REFUSE, DEF_TT_REFUSE);
#ifdef DEBUG
if (refuse) printf("WindowShuffle: refuse = %s\n", refuse);
#endif
if (*refuse && (size = (strlen(refuse) << 1)) &&
(refusetokens = retryallocmem(size, 0l))) {
#ifdef DEBUG
printf("WindowShuffle: size = %ld, refusetokens = 0x%lx\n", size, refusetokens);
#endif
if (ParsePattern(refuse, refusetokens, size) == -1l)
request(COM_NAME ":", RESUME_GADGETS, MSG_REFUSE_TOO_COMPLEX);
#ifdef DEBUG
printf("WindowShuffle: refusetokens = %s\n", refusetokens);
#endif
}
if ((nextacfilter && !CxObjError(nextacfilter)) ||
(prevacfilter && !CxObjError(prevacfilter)) ||
(nextbofilter && !CxObjError(nextbofilter)) ||
(prevbofilter && !CxObjError(prevbofilter))) {
/*
* activate our commodity
*/
ActivateCxObj(broker, 1l);
/*
* now watch our numerous ports
*/
processmessages();
} /* if !CxObjError() */
DeleteCxObjAll(broker);
if (refusetokens) FreeMem(refusetokens, size);
} /* if broker */
#ifdef DEBUG
else printf("main(): CxBroker() failed!\n");
#endif
/*
* delete our message port after replying all pending messages
*/
while (msg = GetMsg(cxport)) ReplyMsg(msg);
DeleteMsgPort(cxport);
} /* if cxport */
#ifdef DEBUG
else printf("main(): CraeteMsgPort() failed!\n");
#endif
ArgArrayDone();
CloseLibrary(IconBase);
} /* if IconBase */
CloseLibrary(CxBase);
} /* if CxBase */
CloseLibrary((struct Library *)IntuitionBase);
} /* if IntuitionBase */
} /* main() */
#define PREV 1
#define TOF 2
#define AC 4
#define BO 6
void processmessages(void)
{
struct Window *win;
struct Message *msg;
unsigned long sigreceived;
unsigned long msgtype;
unsigned long msgid;
unsigned long lock;
unsigned short quit = FALSE;
unsigned char mode;
while (!quit) {
sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag);
#ifdef DEBUG
printf("processmessages(): signal received\n");
#endif
if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
if (sigreceived & cxsigflag) {
while (msg = (struct Message *)GetMsg(cxport)) {
msgid = CxMsgID((CxMsg *)msg);
msgtype = CxMsgType((CxMsg *)msg);
ReplyMsg(msg);
switch (msgtype) {
case CXM_IEVENT:
mode = 0;
switch (msgid) {
case PREVAC: mode = PREV;
case NEXTAC: mode |= AC;
break;
case PREVBO: mode = PREV;
case NEXTBO: mode |= BO;
break;
} /* switch msgid */
lock = LockIBase(0l);
if (mode & PREV) {
/*
* get previous window
*/
if (!(win = prevwindow(IntuitionBase->ActiveWindow))) {
/*
* no prev window; get last window;
* if last window = backdrop || nowintitle ||
* refusewindow get predecessor of lastwindow
*/
if ((win = lastwindow(IntuitionBase->ActiveWindow)) &&
((!backdrop && (win->Flags & WFLG_BACKDROP)) ||
(!nowintitle && !win->Title)) ||
(refusetokens && win->Title && MatchPattern(refusetokens, win->Title)))
win = prevwindow(win);
}
}
else {
/*
* get next window
*/
if (!(win = nextwindow(IntuitionBase->ActiveWindow))) {
/*
* no next window; get first window;
* if first window = backdrop || nowintitle ||
* refusewindow get first window->NextWindow
*/
if ((win = IntuitionBase->ActiveScreen->FirstWindow) &&
((!backdrop && (win->Flags & WFLG_BACKDROP)) ||
(!nowintitle && !win->Title)) ||
(refusetokens && win->Title && MatchPattern(refusetokens, win->Title)))
win = nextwindow(win);
}
}
UnlockIBase(lock);
/*
* now activate and windowtofront the window if (win != NULL)
*/
if (win) {
if ((mode & AC) && (win != IntuitionBase->ActiveWindow))
ActivateWindow(win);
if ((mode & TOF) && (!(win->Flags & WFLG_BACKDROP)))
WindowToFront(win);
}
break;
case CXM_COMMAND:
switch (msgid) {
case CXCMD_UNIQUE:
case CXCMD_KILL:
quit = TRUE;
break;
case CXCMD_DISABLE:
ActivateCxObj(broker, 0l);
break;
case CXCMD_ENABLE:
ActivateCxObj(broker, 1l);
break;
}
break;
} /* switch msgtype */
} /* while CxMsg */
} /* if (sigreceived & cxsigflag) */
} /* while !quit */
ActivateCxObj(broker, 0l);
}
/*
* commodity functions
*/
/*
* get next window
*/
struct Window *nextwindow(register struct Window *win)
{
register struct Window *w = NULL;
if (win) {
while (!w && win->NextWindow) {
w = win = win->NextWindow;
if ((!backdrop && (w->Flags & WFLG_BACKDROP)) ||
(!nowintitle && !w->Title) ||
(refusetokens && w->Title && MatchPattern(refusetokens, w->Title)))
w = NULL;
} /* while !w */
} /* if win */
return(w);
}
/*
* get previous window
*/
struct Window *prevwindow(register struct Window *win)
{
register struct Window *w = NULL;
if (win) {
while (!w && (win != win->WScreen->FirstWindow)) {
for (w = win->WScreen->FirstWindow; w->NextWindow != win; w = w->NextWindow);
if ((!backdrop && (w->Flags & WFLG_BACKDROP)) ||
(!nowintitle && !w->Title) ||
(refusetokens && w->Title && MatchPattern(refusetokens, w->Title))) {
win = w;
w = NULL;
}
} /* while !w */
} /* if win */
return(w);
}
/*
* get last window
*/
struct Window *lastwindow(register struct Window *win)
{
if (win) {
while (win->NextWindow) win = win->NextWindow;
} /* if win */
return(win);
}